package com.xmx.ordercenter.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.xmx.common.rabbitDto.OrderDto;
import com.xmx.common.utils.R;
import com.xmx.ordercenter.dao.CartDao;
import com.xmx.ordercenter.dto.CouponAllVo;
import com.xmx.ordercenter.dto.GoodProductVo;
import com.xmx.ordercenter.dto.Stock_infoTo;
import com.xmx.ordercenter.entity.CartEntity;
import com.xmx.ordercenter.entity.OrderGoodsEntity;
import com.xmx.ordercenter.feign.CouponFeignClient;
import com.xmx.ordercenter.feign.ProductFeignClient;
import com.xmx.ordercenter.feign.PromotionFeignClient;
import com.xmx.ordercenter.feign.UserFeignClient;
import com.xmx.ordercenter.service.CartService;
import com.xmx.ordercenter.service.OrderGoodsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xmx.common.utils.PageUtils;
import com.xmx.common.utils.Query;

import com.xmx.ordercenter.dao.OrderDao;
import com.xmx.ordercenter.entity.OrderEntity;
import com.xmx.ordercenter.service.OrderService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import com.xmx.common.rabbitDto.OrderDto.*;
import sun.rmi.runtime.Log;

import static com.xmx.common.rabbitDto.OrderDto.*;


@Service("orderService")
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderDao, OrderEntity> implements OrderService {

    @Resource
    OrderDao orderDao;


    @Resource
    OrderGoodsService orderGoodsService;

    @Resource
    CartService cartService;

    @Resource
    CouponFeignClient couponFeignClient;

    @Resource
    PromotionFeignClient promotionFeignClient;

    @Resource
    UserFeignClient userFeignClient;

    @Resource
    ProductFeignClient productFeignClient;

    @Resource
    RabbitTemplate rabbitTemplate;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<OrderEntity> page = this.page(
                new Query<OrderEntity>().getPage(params),
                new QueryWrapper<OrderEntity>()
        );

        return new PageUtils(page);
    }

    @Transactional
    public R submitorder(Integer userId, Map<String ,Object> getdata){
        Integer cartId = (Integer) getdata.get( "cartId");
        Integer addressId = (Integer) getdata.get( "addressId");
        Integer couponId = (Integer) getdata.get( "couponId");
        Integer userCouponId = (Integer) getdata.get( "userCouponId");
        String message = (String) getdata.get( "message");
        Integer grouponRulesId = (Integer) getdata.get( "grouponRulesId");
        Integer grouponLinkId = (Integer) getdata.get( "grouponLinkId");


        //TODO:如果是团购项目,验证活动是否有效
        if (grouponRulesId != null && grouponRulesId > 0) {

            R grouponRuleR = promotionFeignClient.getdetailByid(grouponRulesId);
            //找不到记录
            if (ObjectUtils.isEmpty(grouponRuleR.get("grouponRules"))) {
                return R.badArgument();
            }

            if (grouponLinkId != null && grouponLinkId > 0) {
                //团购人数已满

            }

        }
        if (cartId == null || addressId == null || couponId == null) {
            return R.badArgument();
        }
        //TODO 收货地址
        R addrR = userFeignClient.findlistByuid(userId, addressId);
        if(ObjectUtils.isEmpty(addrR.get("data"))){
            return R.badArgument();
        }
        Map checkedAddress = (Map) addrR.get("data");
        //TODO 团购优惠
        BigDecimal grouponPrice = new BigDecimal(0);
        R grouponRuleR = promotionFeignClient.getdetailByid(grouponRulesId);
        // 获取团购价格
        if(!ObjectUtils.isEmpty(grouponRuleR.get("grouponRules"))){
            Map map = (Map) grouponRuleR.get("grouponRules");
            grouponPrice = new BigDecimal(String.valueOf(map.get("discount")));
        }
        //TODO 货品价格
        // TODO:  是否选中购物车,将查询出来的商品存放在购物车集合中
        List<CartEntity> cartAddVoList = new ArrayList<>();

        if (cartId.equals(0)) {
            cartAddVoList = cartService.lambdaQuery().eq(CartEntity::getUserId,userId).list();

        } else {
            CartEntity cartEntity = cartService.getById(cartId);
            cartAddVoList.add( cartEntity);

        }
        if (cartAddVoList.size() == 0) {
            return R.badArgumentValue();
        }

        // TODO:  处理团购价格 （计算商品价格
        BigDecimal checkedGoodsPrice = new BigDecimal(0.00);
        //从购物车中取出商品信息获取其价格
        for (CartEntity cart : cartAddVoList) {
            if(cart==null)
                return R.error("购物车为空");
            if(!ObjectUtils.isEmpty(grouponRuleR.get("grouponRules")) && ((Map)grouponRuleR.get("grouponRules")).get("goodsId").equals(cart.getGoodsId())){
                checkedGoodsPrice = checkedGoodsPrice.add(cart.getPrice().subtract(grouponPrice).multiply(new BigDecimal(cart.getNumber())));
            }else {
                checkedGoodsPrice = checkedGoodsPrice.add(cart.getPrice().multiply(new BigDecimal(cart.getNumber())));
            }
        }

        BigDecimal couponPrice = new BigDecimal(0);
        // 如果couponId=0则没有优惠券，couponId=-1则不使用优惠券
        if (couponId != 0 && couponId != -1) {
            CouponAllVo coupon = checkCoupon( couponId, userCouponId, checkedGoodsPrice, cartAddVoList);
            if (coupon == null) {
                return R.badArgumentValue();
            }
            couponPrice = coupon.getDiscount();
        }

        // 根据订单商品总价计算运费，满88则免运费，否则8元；
        BigDecimal freightPrice = new BigDecimal(0.00);
        if (checkedGoodsPrice.compareTo(new BigDecimal(88)) < 0) {
            freightPrice = new BigDecimal(8);
        }

        // 可以使用的其他钱，例如用户积分
        BigDecimal integralPrice = new BigDecimal(0.00);

        // 订单费用
        BigDecimal orderTotalPrice = checkedGoodsPrice.add(freightPrice).subtract(couponPrice).max(new BigDecimal(0.00));

        BigDecimal actualPrice = orderTotalPrice.subtract(integralPrice);


        Integer orderId = null;
        OrderEntity order = new OrderEntity();

        order.setUserId(userId);
        order.setOrderSn(generateOrderSn(userId));
        order.setOrderStatus(101);
        order.setConsignee((String) checkedAddress.get("name"));
        order.setMobile((String) checkedAddress.get("tel"));
        order.setMessage(message);
        String detailedAddress = (String) checkedAddress.get("province") + checkedAddress.get("city") + checkedAddress.get("county") + " " + checkedAddress.get("addressDetail");
        order.setAddress(detailedAddress);
        order.setGoodsPrice(checkedGoodsPrice);
        order.setFreightPrice(freightPrice);
        order.setCouponPrice(couponPrice);
        order.setIntegralPrice(integralPrice);
        order.setOrderPrice(orderTotalPrice);
        order.setActualPrice(actualPrice);
        // 有团购
        if (!ObjectUtils.isEmpty(grouponRuleR.get("grouponRules"))) {
            order.setGrouponPrice(grouponPrice);    //  团购价格
        } else {
            order.setGrouponPrice(new BigDecimal(0));    //  团购价格
        }
        // 添加订单表项
//        R r = orderFeignClient.addOrder(order);
        int i = orderDao.insert(order);
        orderId = order.getId();

//       TODO 保存订单发送订单消息

//        orderId = (Integer) r.get("id");
        Map mqMap = new HashMap();
        mqMap.put("orderId",orderId);
        mqMap.put("orderSn",order.getOrderSn());
        log.info("========发送创建订单消息===========>>{}",order.getOrderSn());
//        mqMap.put("productList",cartAddVoList);
        rabbitTemplate.convertAndSend(ORDER_EVENT_EXCHANGE,ORDER_CREATE_ROUTING,mqMap);


        for (CartEntity cartAddVo : cartAddVoList) {
            OrderGoodsEntity orderGoods = new OrderGoodsEntity();
            orderGoods.setOrderId(orderId);
            orderGoods.setGoodsId(cartAddVo.getGoodsId());
            orderGoods.setGoodsSn(cartAddVo.getGoodsSn());
            orderGoods.setProductId(cartAddVo.getProductId());
            orderGoods.setGoodsName(cartAddVo.getGoodsName());
            orderGoods.setPicUrl(cartAddVo.getPicUrl());
            orderGoods.setPrice(cartAddVo.getPrice());
            orderGoods.setNumber(cartAddVo.getNumber());
            orderGoods.setSpecifications(cartAddVo.getSpecifications());

//            orderFeignClient.addOrderGoods(orderGoods);
            orderGoodsService.save(orderGoods);
        }


        // 删除购物车里面的商品信息
        if(cartId.equals(0)){
//            orderFeignClient.clearCartGoods(userId);
        }else{
            Integer[] aa = new Integer[]{cartId};
//            orderFeignClient.cartdeleteById(aa);
            cartService.removeById(cartId);
        }

        //TODO 商品货品数量减少
        for (CartEntity checkGoods : cartAddVoList) {
            Integer productId = checkGoods.getProductId();
            Map map = (Map)productFeignClient.goodsproductinfo(productId).get("goodsProduct");
            GoodProductVo product = BeanUtil.mapToBean(map,GoodProductVo.class,false);

            int remainNumber = product.getNumber() - checkGoods.getNumber();
            if (remainNumber < 0) {
                throw new RuntimeException("下单的商品货品数量大于库存量");
            }

            if (productFeignClient.reduceStock(orderId,productId, checkGoods.getNumber() ) == 0) {
                throw new RuntimeException("商品货品库存减少失败");
            }
        }


        //TODO 如果使用了优惠券，设置优惠券使用状态
        if (couponId != 0 && couponId != -1) {
            Map couponUser = (Map) couponFeignClient.infoUsercoupon(userCouponId).get("couponUser");
            couponUser.replace("status",1);
            couponUser.replace("orderId",orderId);
            couponFeignClient.updateCouponUser(couponUser);
        }
//如果是团购项目，添加团购信息
        if (grouponRulesId != null && grouponRulesId > 0) {

        }

        // 订单支付超期任务
//        taskService.addTask(new OrderUnpaidTask(orderId));

        Map<String, Object> data = new HashMap<>();
        data.put("orderId", orderId);
        if (grouponRulesId != null && grouponRulesId > 0) {
            data.put("grouponLinkId", grouponLinkId);
        }
        else {
            data.put("grouponLinkId", 0);
        }

        return R.ok().put("data",data);
    }

    public CouponAllVo checkCoupon(Integer couponId, Integer userCouponId, BigDecimal checkedGoodsPrice, List<CartEntity> cartListi){
        R infocoupon = couponFeignClient.infocoupon(couponId);
        CouponAllVo couponAllVo = BeanUtil.mapToBean((Map) infocoupon.get("coupon"), CouponAllVo.class,true);
        if(couponAllVo == null)
            return null;
        Map couponUser = (Map) couponFeignClient.infoUsercoupon(userCouponId).get("couponUser");
        //如果找不到
        if(couponUser == null) {
            return null;
        }else if(!couponId.equals(couponUser.get("couponId"))){
            return null;
        }

        // 检查是否超期

        LocalDateTime now = LocalDateTime.now();
        if(couponAllVo.getTimeType()==1){
            if(now.isBefore(couponAllVo.getStartTime())|| now.isAfter(couponAllVo.getEndTime())){
                return null;
            }
        }else if(couponAllVo.getTimeType()==0){

            LocalDateTime exprired = LocalDateTime.parse((String)couponUser.get("addTime")).plusDays(couponAllVo.getDays());
            if(now.isAfter(exprired)){
                return null;
            }
        }
        else {
            return null;
        }

        //检测商品是否符合标准
        if(couponAllVo.getGoodsType().equals(1) || couponAllVo.getGoodsType().equals(2)){
            for (CartEntity cartAddVo : cartListi) {
                Integer key = couponAllVo.getGoodsType().equals(1)? cartAddVo.getGoodsId():0;
            }
        }

        // 检测订单状态

        if (!couponAllVo.getStatus().equals(0)) {
            return null;
        }
        // 检测是否满足最低消费
        if (checkedGoodsPrice.compareTo(couponAllVo.getMin()) == -1) {
            return null;
        }
        return couponAllVo;
    }

    public String generateOrderSn(Integer userId) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMdd");
        String now = df.format(LocalDate.now());
        String orderSn = now + getRandomNum(6);

        QueryWrapper<OrderEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id",userId);
        queryWrapper.eq("order_sn",orderSn);
        int count = this.count(queryWrapper);

        while (count != 0) {
            orderSn = now + getRandomNum(6);
        }
        return orderSn;
    }

    private String getRandomNum(Integer num) {
        String base = "0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < num; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }

}